{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# hvPlot.line\n",
    "\n",
    "```{eval-rst}\n",
    ".. currentmodule:: hvplot\n",
    "\n",
    ".. automethod:: hvPlot.line\n",
    "```\n",
    "\n",
    "## Backend-specific styling options\n",
    "\n",
    "```{eval-rst}\n",
    ".. backend-styling-options:: line\n",
    "```\n",
    "\n",
    "## Examples\n",
    "\n",
    "### Basic line plot\n",
    "\n",
    "This example shows how to create a simple line plot."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "import hvplot.pandas  # noqa\n",
    "import pandas as pd\n",
    "\n",
    "df = pd.DataFrame({\"x\": [0, 1, 2, 3], \"y\": [0, 1, 4, 9]})\n",
    "\n",
    "df.hvplot.line(x=\"x\", y=\"y\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Multiple line plot\n",
    "\n",
    "This dataset consists of a `date` column and 6 different stocks columns. In this example we only set `x`, hvPlot infers it should attempt to display all the remaining columns as lines. Alternatively, we could explicitly set `y` to the list of columns."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "import hvplot.pandas  # noqa\n",
    "\n",
    "df = hvplot.sampledata.stocks(\"pandas\")\n",
    "\n",
    "df.hvplot.line(x=\"date\", group_label=\"Stocks\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Grouping by categories\n",
    "\n",
    "To distinguish categories visually, you can use the [`by`](option-by) option. This automatically colors lines based on the specified column, returning a [HoloViews NdOverlay](https://holoviews.org/reference/containers/bokeh/NdOverlay.html).\n",
    "\n",
    ":::{note}\n",
    "The [`color`](option-color) cannot be used to vectorize coloring each individual line.\n",
    ":::"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "import hvplot.pandas  # noqa\n",
    "\n",
    "df = hvplot.sampledata.stocks(\"pandas\").set_index(\"date\").melt(ignore_index=False, var_name=\"stock\")\n",
    "print(df.head(2))\n",
    "\n",
    "df.hvplot.line(by=\"stock\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Line plot with markers\n",
    "\n",
    "The Bokeh plotting backend doesn't offer options to style the markers of a line glyph. So we simply overlay a `scatter` plot. Visit the [`scatter` reference](scatter-marker-style) to find how to customize the marker style."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "import hvplot.pandas  # noqa\n",
    "import pandas as pd\n",
    "\n",
    "df = pd.DataFrame({\"x\": [0, 1, 2, 3], \"y\": [0, 1, 4, 9]})\n",
    "\n",
    "df.hvplot.line(x=\"x\", y=\"y\") *\\\n",
    "df.hvplot.scatter(x=\"x\", y=\"y\", marker=\"*\", s=100, padding=0.1)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "The Matplotlib plotting backend offers some simple ways to directly style line markers."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "import hvplot.pandas  # noqa\n",
    "import pandas as pd\n",
    "hvplot.extension(\"matplotlib\")\n",
    "\n",
    "df = pd.DataFrame({\"x\": [0, 1, 2, 3], \"y\": [0, 1, 4, 9]})\n",
    "\n",
    "df.hvplot.line(x=\"x\", y=\"y\", marker=\"*\", ms=10, padding=0.1)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Line dash\n",
    "\n",
    "The Bokeh plotting backend accepts these values for the `line_dash` keyword:\n",
    "- One of `'solid'`, `'dashed'`, `'dotted'`, `'dotdash'`, `'dashdot'`.\n",
    "- A dash pattern (following the HTML5 Canvas dash specification) as a tuple of integers, which specify the lengths of dashes and gaps in a stroked line."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "import hvplot.pandas  # noqa\n",
    "import pandas as pd\n",
    "\n",
    "df = pd.DataFrame({\"x\": [0, 1, 2, 3], \"y\": [0, 1, 4, 9]})\n",
    "\n",
    "plot_opts = dict(x=\"x\", y=\"y\", width=300, height=200)\n",
    "(\n",
    "    df.hvplot.line(line_dash=\"dashed\", title=\"dashed\", **plot_opts) +\n",
    "    df.hvplot.line(line_dash=\"dotted\", title=\"dotted\", **plot_opts) +\n",
    "    df.hvplot.line(line_dash=\"dotdash\", title=\"dotdash\", **plot_opts) +\n",
    "    df.hvplot.line(line_dash=\"dashdot\", title=\"dashdot\", **plot_opts) +\n",
    "    df.hvplot.line(line_dash=(20, 10), title=\"Dash pattern (20, 10)\", **plot_opts) +\n",
    "    df.hvplot.line(line_dash=(20, 10, 5), title=\"Dash pattern (20, 10, 5)\", **plot_opts)\n",
    ").cols(2)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "The Matplotlib backend accepts these values for the `linestyle` keyword:\n",
    "- One of `'-'`/`'solid'`, `'--'`/`'dashed'`, `'-.'`/`'dashdot'`, `':'`/`'dotted'`\n",
    "- A dash tuple `(offset, (on_off_seq))`. For example, `(0, (3, 10, 1, 15))` means (3pt line, 10pt space, 1pt line, 15pt space) with no offset, while `(5, (10, 3))`, means (10pt line, 3pt space), but skip the first 5pt line.\n",
    "\n",
    "Find more information about Matplotlib linestyles in [its documentation](https://matplotlib.org/stable/gallery/lines_bars_and_markers/linestyles.html)."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "import hvplot.pandas  # noqa\n",
    "import pandas as pd\n",
    "hvplot.extension(\"matplotlib\")\n",
    "\n",
    "df = pd.DataFrame({\"x\": [0, 1, 2, 3], \"y\": [0, 1, 4, 9]})\n",
    "\n",
    "plot_opts = dict(x=\"x\", y=\"y\", width=300, height=200)\n",
    "(\n",
    "    df.hvplot.line(linestyle=\"dashed\", title=\"dashed\", **plot_opts) +\n",
    "    df.hvplot.line(linestyle=\"dotted\", title=\"dotted\", **plot_opts) +\n",
    "    df.hvplot.line(linestyle=\"dashdot\", title=\"dashdot\", **plot_opts) +\n",
    "    df.hvplot.line(linestyle=(0, (1, 10)), title=\"dash tuple (0, (1, 10))\", **plot_opts)\n",
    ").cols(2)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Set the line width\n",
    "\n",
    "The line width can be controlled with the `line_width` keyword for the Bokeh plotting backend and the `linewidth` keyword for the Maplotlib plotting backend."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "import hvplot.pandas  # noqa\n",
    "import pandas as pd\n",
    "\n",
    "df = pd.DataFrame({\"x\": [0, 1, 2, 3], \"y\": [0, 1, 4, 9]})\n",
    "\n",
    "df.hvplot.line(x=\"x\", y=\"x\", line_width=10)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Xarray example\n",
    "\n",
    "We plot the evolution of the air temperature at a specific lat/lon location."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "import hvplot.xarray  # noqa\n",
    "\n",
    "ds = hvplot.sampledata.air_temperature(\"xarray\").sel(lon=285.,lat=40.)\n",
    "\n",
    "ds.hvplot.line(y=\"air\")"
   ]
  }
 ],
 "metadata": {
  "language_info": {
   "name": "python",
   "pygments_lexer": "ipython3"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}
